class UserHelper {
	private static _instance: UserHelper;
	public static get instance() {
		if (this._instance == null) {
			this._instance = new UserHelper();
		}
		return this._instance;
	}

	private BASE_URL: string = Constants.HTTP_SERVER_URL + "/user";
	private mSessionID: string = null;

	private constructor() {
		this.mSessionID = wx.getStorageSync("LoginSessionID");
	}

	//返回值是布尔值，表示是否是首次登陆本程序
	public async login() {
		return new Promise<boolean>((resolve, reject) => {
			wx.login({
				success: (res) => {
					wx.request({
						url: this.BASE_URL + "/loginByWechat",
						method: "GET",
						data: {
							code: res.code
						},
						success: (res) => {
							if (res.statusCode == 200 || res.data["errorCode"] != 0) {
								let result = <{}>res.data;
								this.mSessionID = <string>result["sessionID"];
								wx.setStorageSync("LoginSessionID", this.mSessionID);
								resolve(<boolean>result["firstLogin"]);
							} else {
								if (res.statusCode != 200) reject("statusCode=" + res.statusCode);
								else reject("errorCode=" + res.data["errorCode"]);
							}
						},
						fail: function (res) {
							reject(res);
						}
					})
				},
				fail: function (res) {
					reject(res);
				}
			})
		});
	}

	public async initUserInfo(userInfo: wx.UserInfo) {
		return new Promise((resolve, reject) => {
			if (!this.hasLogin()) {
				reject("Can not init UserInfo before login!");
			}
			wx.request({
				url: this.BASE_URL + "/updateUserInfoByWechat?sessionID=" + this.mSessionID,
				method: "POST",
				data: userInfo,
				success: (res) => {
					if (res.statusCode == 200) {
						resolve();
					}
				},
				fail: (res) => {
					reject(res)
				}
			})
		});
	}

	public async getUserInfo() {
		return new Promise<EtreeUserInfo>((resolve, reject) => {
			if (!this.hasLogin()) {
				reject("Can not get UserInfo before login!");
			}
			wx.request({
				url: this.BASE_URL + "/getUserInfo",
				method: "GET",
				data: {
					sessionID: this.mSessionID
				},
				success: (res) => {
					if (res.statusCode == 200) {
						resolve(<EtreeUserInfo>res.data["data"]);
					} else {
						reject("statusCode=" + res.statusCode);
					}
				},
				fail: (res) => {
					reject(res);
				}
			});
		});
	}

	public async updateUserInfo(updatedUserInfo: EtreeUserInfo) {
		return new Promise((resolve, reject) => {
			if (!this.hasLogin()) {
				reject("Can not update UserInfo before login!");
			}
			wx.request({
				url: this.BASE_URL + "/updateUserInfo?sessionID=" + this.mSessionID,
				method: "POST",
				data: updatedUserInfo,
				success: (res) => {
					if (res.statusCode == 200) {
						resolve();
					}
				},
				fail: (res) => {
					reject(res)
				}
			});
		});
	}


	public hasLogin(): boolean {
		return this.mSessionID != "";
	}
}

interface EtreeUserInfo {
	etreeID: string,
	name: string,
	sex: string,
	age: number,
	dept: string,
	registerDate: Date,
	avatarSrc: string
}